#pragma once

#include "src/TGN.h"

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

extern char *StringToArray(String *st);

namespace TGN
{
	/// <summary> 
	/// Summary for PreviewAni
	///
	/// WARNING: If you change the name of this class, you will need to change the 
	///          'Resource File Name' property for the managed resource compiler tool 
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public __gc class PreviewAni : public System::Windows::Forms::Form
	{
	public: 
		PreviewAni(void)
		{
			InitializeComponent();

			ani = NULL;
			blitter = NULL;

			playing = true;
			quit = false;
			currFrame = 0;
			delay = 0;
		}
        
	protected: 
		void Dispose(Boolean disposing)
		{
			if (disposing && components)
			{
				components->Dispose();
			}
			__super::Dispose(disposing);
		}
	private: System::Windows::Forms::PictureBox *  AniPreview;
	private: System::Windows::Forms::Button *  AniPlay;
	private: System::Windows::Forms::Button *  AniStop;
	private: System::Windows::Forms::Button *  AniDone;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container* components;

		TGNAni* ani;

		Graphics *blitter;
		Image *fullImage;

		Rectangle src, dest;
		int currFrame;
		bool playing;
		bool quit;

		int delay;

		Thread *animation;

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			System::Resources::ResourceManager *  resources = new System::Resources::ResourceManager(__typeof(TGN::PreviewAni));
			this->AniPreview = new System::Windows::Forms::PictureBox();
			this->AniPlay = new System::Windows::Forms::Button();
			this->AniStop = new System::Windows::Forms::Button();
			this->AniDone = new System::Windows::Forms::Button();
			this->SuspendLayout();
			// 
			// AniPreview
			// 
			this->AniPreview->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
			this->AniPreview->Location = System::Drawing::Point(8, 8);
			this->AniPreview->Name = S"AniPreview";
			this->AniPreview->Size = System::Drawing::Size(264, 184);
			this->AniPreview->TabIndex = 0;
			this->AniPreview->TabStop = false;
			// 
			// AniPlay
			// 
			this->AniPlay->Location = System::Drawing::Point(8, 192);
			this->AniPlay->Name = S"AniPlay";
			this->AniPlay->Size = System::Drawing::Size(88, 24);
			this->AniPlay->TabIndex = 1;
			this->AniPlay->Text = S"Play";
			this->AniPlay->Click += new System::EventHandler(this, AniPlay_Click);
			// 
			// AniStop
			// 
			this->AniStop->Location = System::Drawing::Point(96, 192);
			this->AniStop->Name = S"AniStop";
			this->AniStop->Size = System::Drawing::Size(88, 24);
			this->AniStop->TabIndex = 2;
			this->AniStop->Text = S"Stop";
			this->AniStop->Click += new System::EventHandler(this, AniStop_Click);
			// 
			// AniDone
			// 
			this->AniDone->Location = System::Drawing::Point(184, 192);
			this->AniDone->Name = S"AniDone";
			this->AniDone->Size = System::Drawing::Size(88, 24);
			this->AniDone->TabIndex = 3;
			this->AniDone->Text = S"Done";
			this->AniDone->Click += new System::EventHandler(this, AniDone_Click);
			// 
			// PreviewAni
			// 
			this->AutoScaleBaseSize = System::Drawing::Size(6, 15);
			this->ClientSize = System::Drawing::Size(288, 224);
			this->Controls->Add(this->AniDone);
			this->Controls->Add(this->AniStop);
			this->Controls->Add(this->AniPlay);
			this->Controls->Add(this->AniPreview);
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
			this->Icon = (__try_cast<System::Drawing::Icon *  >(resources->GetObject(S"$this.Icon")));
			this->MaximizeBox = false;
			this->MinimizeBox = false;
			this->Name = S"PreviewAni";
			this->Text = S"Preview Animation";
			this->Closing += new System::ComponentModel::CancelEventHandler(this, PreviewAni_Closing);
			this->ResumeLayout(false);

		}		


		public: void Display(char *filename, TGNAni *data)
		{
			fullImage = Image::FromFile(ArrayToString(filename));
			blitter = Graphics::FromImage(fullImage);
			ani = data;

			ThreadStart *start = new ThreadStart(this, Animate);
			animation = new Thread(start);
			animation->Start();

			quit = false;
			playing = true;

			this->ShowDialog();
		}

		private: void Animate()
		{
			while(!quit)
			{
				while(playing)
				{

					delay = System::Environment::TickCount;

					if(currFrame >= ani->numFrames)
						currFrame = 0;

					src.X = ani->frames[currFrame].x;
					src.Y = ani->frames[currFrame].y;
					src.Width = ani->frames[currFrame].w;
					src.Height = ani->frames[currFrame].h;

					dest.X =  (AniPreview->Width / 2) - ani->frames[currFrame].hotx;
					dest.Y =  (AniPreview->Height / 2) - ani->frames[currFrame].hoty;
					dest.Width = ani->frames[currFrame].w;
					dest.Height = ani->frames[currFrame].h;

					Bitmap *frame = new Bitmap(AniPreview->Width, AniPreview->Height);
					blitter = Graphics::FromImage(frame);
			
					blitter->DrawImage(fullImage, dest, src, GraphicsUnit::Pixel);

					AniPreview->Image = frame;

					while((System::Environment::TickCount - delay) <= ani->frames[currFrame].delay);

					currFrame++;

					Thread::Sleep(0);
				}

				Thread::Sleep(0);
			}
		}
	private: System::Void AniDone_Click(System::Object *  sender, System::EventArgs *  e)
			 {
				 quit = true;
				 animation->Abort();
				 this->Hide();
			 }

private: System::Void AniPlay_Click(System::Object *  sender, System::EventArgs *  e)
		 {
			 playing = true;
		 }

private: System::Void AniStop_Click(System::Object *  sender, System::EventArgs *  e)
		 {
			 playing = false;
		 }
private: System::Void PreviewAni_Closing(System::Object *  sender, System::ComponentModel::CancelEventArgs *  e)
		 {
			 quit = true;
			 animation->Abort();
		 }

};
}